
/**
 * @brief
 *
 * @version  0.1
 * @author   wuxingchuang
 * @date     2025.06.19
 *          _
 *      ___| |__   ___ _ __   __ _  ___  _ __   __ _
 *     / __| '_ \ / _ \ '_ \ / _` |/ _ \| '_ \ / _` |
 *     \__ \ | | |  __/ | | | (_| | (_) | | | | (_| |
 *     |___/_| |_|\___|_| |_|\__, |\___/|_| |_|\__, |
 *                           |___/             |___/
 * @copyright (c) 2024 by 神工仿真, All Rights Reserved.
 */
#pragma once
#include "Utility/Algebra/Point.h"

#include "DataStructure/Common/Id.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Common/SGObject.h"
#include "DataStructure/Input/Coordinate/CoordTypes.h"

SG_DATASTRUCTURE_FEM_NAMESPACE_OPEN

struct TRANSFORMATIONData : public SGObject
{
    TRANSFORMATIONData ()
    {
        // m_RDATAList.resize (12);  // 12 real data
    };
    /**
     *  1 = rectangular
     *  2 = cylindrical
     *  3 = spherical
     *  4 = convective -- defined on a GMCURV+GMSURF pair
     *  5 = convective -- defined on a GMSURF
     *  6 = convective -- defined on a FEEDGE+FEFACE pair
     *  7 = convective -- defined on a FEFAC
     */
    enum class Type : SG::DataStructure::Common::I64
    {
        Undefined   = 0,  ///< Undefined transformation type
        Rectangular = 1,  ///< Rectangular transformation
        Cylindrical = 2,  ///< Cylindrical transformation
        Spherical   = 3,  ///< Spherical transformation
        Convective1 = 4,  ///< Convective transformation defined on a GMCURV+GMSURF pair
        Convective2 = 5,  ///< Convective transformation defined on a GMSURF
        Convective3 = 6,  ///< Convective transformation defined on a FEEDGE+FEFACE pair
        Convective4 = 7   ///< Convective transformation defined on a FEFAC
    };

    struct IDATAData
    {
        SG::DataStructure::Common::I64 m_DATA = 0;  ///< Integer data
    };
    struct RDATAData
    {
        SG::DataStructure::Common::Real m_DATA = 0.0;            ///< Real data
    };

    TRANSFORMATIONData::Type      m_TYPE     = Type::Undefined;  ///< Type of system
    SG::DataStructure::Common::Id m_domainId = 0;                ///<

    std::vector<IDATAData> m_IDATAList;
    std::vector<RDATAData> m_RDATAList;

    void setType (SG::DataStructure::FEM::CoordTypes ctype)
    {
        if (ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Cartesian
            || ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Cartesian2)
        {
            m_TYPE = SG::DataStructure::FEM::TRANSFORMATIONData::Type::Rectangular;
        }
        else if (ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Cylinder
                 || ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Cylinder2)
        {
            m_TYPE = SG::DataStructure::FEM::TRANSFORMATIONData::Type::Cylindrical;
        }
        else if (ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Sphere
                 || ctype == SG::DataStructure::FEM::CoordTypes::COORDTYPE_Sphere2)
        {
            m_TYPE = SG::DataStructure::FEM::TRANSFORMATIONData::Type::Spherical;
        }
    };

    void setOrigin (const SG::Algebra::Point& origin)
    {
        m_RDATAList[0].m_DATA = origin.m_x;
        m_RDATAList[1].m_DATA = origin.m_y;
        m_RDATAList[2].m_DATA = origin.m_z;
    };

    void setBaseX (const SG::Algebra::Vector3D& xv)
    {
        m_RDATAList[3].m_DATA = xv.m_x;
        m_RDATAList[6].m_DATA = xv.m_y;
        m_RDATAList[9].m_DATA = xv.m_z;
    };

    void setBaseY (const SG::Algebra::Vector3D& yv)
    {
        m_RDATAList[4].m_DATA  = yv.m_x;
        m_RDATAList[7].m_DATA  = yv.m_y;
        m_RDATAList[10].m_DATA = yv.m_z;
    };

    void setBaseZ (const SG::Algebra::Vector3D& zv)
    {
        m_RDATAList[5].m_DATA  = zv.m_x;
        m_RDATAList[8].m_DATA  = zv.m_y;
        m_RDATAList[11].m_DATA = zv.m_z;
    };
};

///@{ @brief operator override
DECLSPEC bool operator== (const TRANSFORMATIONData::IDATAData& val1, const TRANSFORMATIONData::IDATAData& val2);
DECLSPEC bool operator== (const TRANSFORMATIONData::RDATAData& val1, const TRANSFORMATIONData::RDATAData& val2);

DECLSPEC bool operator== (const TRANSFORMATIONData& val1, const TRANSFORMATIONData& val2);
///}@
SG_DATASTRUCTURE_FEM_NAMESPACE_CLOSE
